﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lacrima.Gobang.App
{
    /// <summary>
    /// 五子棋的规则
    /// </summary>
    class Rule
    {
        /// <summary>
        /// 判断是否在该点存在棋子,存在返回true;
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <param name="ChessBoard"></param>
        /// <returns></returns>
        public static bool IsExists(int m, int n, int[,] ChessBoard)
        {
            if (ChessBoard[m, n] < 2) return true;
            else return false;
        }
        /// <summary>
        /// 判断结果 1双三禁手;2双四禁手;3长联禁手;4胜利;5平局;6继续
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <param name="arrchessboard"></param>
        /// <returns></returns>
        public static int FIR_Result(int m, int n, int[,] arrchessboard)
        {
            int[] arrf = new int[4];
            //四个方向的连子个数,横,竖,左斜线,右斜线
            arrf[0] = Xnum(m, n, arrchessboard);
            arrf[1] = Ynum(m, n, arrchessboard);
            arrf[2] = XYnum(m, n, arrchessboard);
            arrf[3] = YXnum(m, n, arrchessboard);
            //判断在该点是否可以下
            if (IsFail(arrf, arrchessboard[m, n]) > 0)
            {
                return IsFail(arrf, arrchessboard[m, n]);
            }
            else
            {
                //是否胜利
                if (IsWin(arrf) == true) return 4;//胜利 4
                else
                {
                    if (IsPing(arrchessboard) == true) return 5;//平局 5
                    else return 6;//继续 6
                }
            }
        }

        #region 是否已经胜利
        /// <summary>
        /// 是否已经胜利
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        private static bool IsWin(int[] arr)
        {
            for (int i = 0; i < 4; i++)
            {
                if (Math.Abs(arr[i]) == 5)
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region 平局即所有的落子点都下满了.落子为1,0.空着表示2
        /// <summary>
        /// 平局即所有的落子点都下满了.落子为1,0.空着表示2
        /// </summary>
        /// <param name="arrchessboard"></param>
        /// <returns></returns>
        private static bool IsPing(int[,] arrchessboard)
        {
            for (int i = 0; i < 15; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    if (arrchessboard[i, j] == 2) return false;
                }
            }
            return true;
        }
        #endregion

        #region 判断在该点下子会不会犯规.因为黑子先手下棋会有很大的优势,所以需要一些规则来限制先手下棋
        /// <summary>
        /// 判断在该点下子会不会犯规.因为黑子先手下棋会有很大的优势,所以需要一些规则来限制先手下棋
        /// 即黑子不能走双三,双四,不能长联,只能走四冲三
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="stoneflag"></param>
        /// <returns></returns>
        public static int IsFail(int[] arr, int stoneflag)
        {
            if (stoneflag == 1) return 0; //0表示没有失败,即可以下子
            else
            {
                int num = 0;
                //活双三禁手
                for (int i = 0; i < 4; i++)
                {
                    if (arr[i] == 3) num++;
                }
                if (num > 1) return 1;//双三禁手 1
                num = 0;
                for (int i = 0; i < 4; i++)
                {
                    if (arr[i] == 4) num++;
                }
                if (num > 1) return 2;//双四禁手 2
                num = 0;
                for (int i = 0; i < 4; i++)
                {
                    if (arr[i] > 5) num++;
                }
                if (num > 1) return 3;//长联禁手 3
            }
            return 0;
        }

        #endregion

        #region 返回四个方向的连续棋子数
        public static int Xnum(int m, int n, int[,] arrchessboard)
        {
            //正东方向
            int flag = 0, num = 1;
            int i = m + 1;
            while (i < 15)
            {
                if (arrchessboard[m, n] == arrchessboard[i, n])
                {
                    num++;
                    i++;
                }
                else break;
            }
            if (i == 15) flag++;
            else
            {
                if (arrchessboard[i, n] != 2) flag++;
            }

            //正西方向
            i = m - 1;
            while (i >= 0)
            {
                if (arrchessboard[m, n] == arrchessboard[i, n])
                {
                    num++;
                    i--;
                }
                else break;
            }
            if (i == -1) flag++;
            else
            {
                if (arrchessboard[i, n] != 2) flag++;
            }
            //当flag=2时如两种情况:1,两头都已经在边,或者两头都有其它的子,即X轴已经占满;2,一头有子一头到边
            //flag=2表示两边都堵住了.已经没有发展的前途,除非是大于等于5个,但这种情况很少
            if (flag == 2) return -num;
            else
            {
                //一头到边或者有子,即使是3个也不是活3
                if (flag == 1 && num == 3) return -num;
                else return num;
            }
        }

        public static int Ynum(int m, int n, int[,] arrchessboard)
        {
            int num = 1, flag = 0;
            //正南方向
            int i = n + 1;
            while (i < 15)
            {
                if (arrchessboard[m, n] == arrchessboard[m, i])
                {
                    num++;
                    i++;
                }
                else break;
            }
            if (i == 15) flag++;
            else
            {
                if (arrchessboard[m, i] != 2) flag++;
            }
            //正北方向
            i = n - 1;
            while (i >= 0)
            {
                if (arrchessboard[m, n] == arrchessboard[m, i])
                {
                    num++;
                    i--;
                }
                else break;
            }
            if (i == -1) flag++;
            else
            {
                if (arrchessboard[m, i] != 2) flag++;
            }
            if (flag == 2) return -num;
            else
            {
                if (flag == 1 && num == 3) return -num;
                else return num;
            }
        }

        public static int YXnum(int m, int n, int[,] arrchessboar)
        {
            int num = 1, flag = 0;
            //东南方向
            int i = m + 1, j = n + 1;
            while (i < 15 && j < 15)
            {
                if (arrchessboar[m, n] == arrchessboar[i, j])
                {
                    num++;
                    i++;
                    j++;
                }
                else break;
            }
            if (i == 15 || j == 15) flag++;
            else
            {
                if (arrchessboar[i, j] != 2) flag++;
            }
            //西北方向
            i = m - 1;
            j = n - 1;
            while (i >= 0 && j >= 0)
            {
                if (arrchessboar[m, n] == arrchessboar[i, j])
                {
                    num++;
                    i--;
                    j--;
                }
                else break;
            }
            if (i == -1 || j == -1) flag++;
            else
            {
                if (arrchessboar[i, j] != 2) flag++;
            }
            if (flag == 2) return -num;
            else
            {
                if (flag == 1 && num == 3) return -num;
                else return num;
            }
        }

        public static int XYnum(int m, int n, int[,] arrchessboar)
        {
            int num = 1, flag = 0;
            //东北方向
            int i = m + 1, j = n - 1;
            while (i < 15 && j >= 0)
            {
                if (arrchessboar[i, j] == arrchessboar[m, n])
                {
                    num++;
                    i++;
                    j--;
                }
                else break;
            }
            if (i == 15 || j == -1) flag++;
            else
            {
                if (arrchessboar[i, j] != 2) flag++;
            }
            //西南方向
            i = m - 1; j = n + 1;
            while (i >= 0 && j < 15)
            {
                if (arrchessboar[i, j] == arrchessboar[m, n])
                {
                    num++;
                    i--;
                    j++;
                }
                else break;
            }
            if (i == -1 || j == 15) flag++;
            else
            {
                if (arrchessboar[i, j] != 2) flag++;
            }
            if (flag == 2) return -num;
            else
            {
                if (flag == 1 && num == 3) return -num;
                else return num;
            }
        }
        #endregion
    }
}
